# -*- coding: utf-8 -*-
import arcpy
import pandas as pd
import os
import sys
import argparse

# 获取当前脚本所在目录的父目录
current_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(current_dir)
sys.path.append(parent_dir)
from utils.utools import timer

@timer
def join_with_csv_to_new_feature(input_fc_fullpath, id_field_fc, csv_path, id_field_csv, output_fc_fullpath):
    """
    使用 pandas 将一个点要素类与 CSV 文件进行属性连接，并生成一个新的点要素类。
    此方法比传统的 arcpy 连接和复制要素在处理大数据量时更高效。

    参数:
        input_fc_fullpath (str):    输入的点要素类路径。
        csv_path (str):             用于连接的 CSV 文件路径。
        output_fc_fullpath (str):   要创建的新点要素类的完整路径。
        id_field_fc (str):          输入要素类中用于连接的字段名。
        id_field_csv (str):         CSV 文件中用于连接的列名。

    返回:
        None
    """
    out_gdb_path = os.path.dirname(output_fc_fullpath)
    arcpy.env.workspace = out_gdb_path
    arcpy.env.overwriteOutput = True

    try:
        # ----------------------------
        # 0. 强制删除旧的输出要素类，确保每次都是全新创建
        # ----------------------------
        if arcpy.Exists(output_fc_fullpath):
            arcpy.AddMessage("检测到旧的输出要素类，正在删除:{}".format(output_fc_fullpath))
            arcpy.Delete_management(output_fc_fullpath)

        # ----------------------------
        # 1. 读取要素类到DataFrame（保留坐标）
        # ----------------------------
        arcpy.AddMessage("正在读取要素类:{}".format(input_fc_fullpath))
        fields = [id_field_fc, "SHAPE@XY"]
        data = [row for row in arcpy.da.SearchCursor(input_fc_fullpath, fields)]
        df_fc = pd.DataFrame(data, columns=[id_field_fc, "SHAPE@XY"])

        # ----------------------------
        # 2. 读取CSV文件并清理字段名
        # ----------------------------
        arcpy.AddMessage("正在读取CSV文件:{}".format(csv_path))
        df_csv = pd.read_csv(csv_path)

        # 清理CSV列名，确保它们符合ArcGIS字段名规范

        valid_cols = {}
        for col in df_csv.columns:
            valid_col = arcpy.ValidateFieldName(col, out_gdb_path)
            valid_cols[col] = valid_col
        df_csv.rename(columns=valid_cols, inplace=True)

        # 如果连接键被重命名了，需要更新它
        if id_field_csv in valid_cols:
            id_field_csv = valid_cols[id_field_csv]

        # ----------------------------
        # 3. 按id字段连接两个表
        # ----------------------------
        arcpy.AddMessage("正在执行表连接...")
        df_merged = pd.merge(df_fc, df_csv, left_on=id_field_fc, right_on=id_field_csv, how="left")

        # ----------------------------
        # 4. 创建输出要素类并添加字段
        # ----------------------------
        out_fc_name = os.path.basename(output_fc_fullpath)

        arcpy.AddMessage("正在创建新的要素类:{}".format(output_fc_fullpath))
        arcpy.CreateFeatureclass_management(
            out_path=out_gdb_path,
            out_name=out_fc_name,
            geometry_type="POINT",
            spatial_reference=arcpy.Describe(input_fc_fullpath).spatialReference
        )

        arcpy.AddMessage("正在添加字段...")
        # 1. 添加来自原始要素类的ID字段
        id_field_obj = [f for f in arcpy.ListFields(input_fc_fullpath) if f.name == id_field_fc][0]
        arcpy.AddField_management(output_fc_fullpath, id_field_obj.name, id_field_obj.type,
                                  field_precision=id_field_obj.precision,
                                  field_scale=id_field_obj.scale,
                                  field_length=id_field_obj.length,
                                  field_alias=id_field_obj.aliasName)
        arcpy.AddMessage("  - 已添加字段:{}".format(id_field_obj.name))

        # 2. 添加来自CSV的字段（排除连接键）
        csv_output_fields = [col for col in df_csv.columns if col != id_field_csv]
        for col_name in csv_output_fields:
            field_length = 255  # 默认文本长度
            dtype = df_csv[col_name].dtype
            if dtype == 'int64':
                field_type = "LONG"
            elif dtype == 'float64':
                field_type = "DOUBLE"
            else:
                field_type = "TEXT"

            arcpy.AddField_management(output_fc_fullpath, col_name, field_type, field_length=field_length)
            arcpy.AddMessage("  - 已添加字段:{}".format(col_name))

        # ----------------------------
        # 5. 将结果写回为新的点要素类
        # ----------------------------
        out_fields = [id_field_fc, "SHAPE@XY"] + csv_output_fields
        arcpy.AddMessage("正在写入数据...")
        with arcpy.da.InsertCursor(output_fc_fullpath, out_fields) as cursor:
            for index, row in df_merged.iterrows():
                # 兼容旧版pandas，使用 pd.notnull
                out_row = [row[id_field_fc], row["SHAPE@XY"]] + [row[col] if pd.notnull(row[col]) else None for col in
                                                                 csv_output_fields]
                cursor.insertRow(out_row)

        arcpy.AddMessage("\n处理完成！新要素类已保存至：{}".format(output_fc_fullpath))

    except Exception as e:
        # 捕获并打印任何异常，使脚本更健壮
        arcpy.AddMessage("\n脚本执行过程中发生错误:")
        import traceback
        print(traceback.format_exc())
    return output_fc_fullpath

def tt():
    # 设置工作环境
    # 这样做的好处是，函数逻辑和参数配置分离，更易于修改
    params = {
        "input_fc_fullpath": r"C:\Users\DDTwo\Documents\ArcGIS\Projects\gwlsaAngDa\gwlsaAngDa.gdb\RU202220905_sub",
        "csv_path": r"C:\Users\DDTwo\Documents\ArcGIS\Projects\gwlsaAngDa\wlr_weights_1to4_all_loop1.csv",
        "output_fc_fullpath": r"C:\Users\DDTwo\Documents\ArcGIS\Projects\gwlsaAngDa\gwlsaAngDa.gdb\Output_joined_Points",
        "id_field_fc": "id",
        "id_field_csv": "# GeoID"
    }

    # 调用主函数
    join_with_csv_to_new_feature(**params)

def main():
    parser = argparse.ArgumentParser(description='连接CSV并另存为新的要素类')
    parser.add_argument('--input_fc_fullpath', required=True, help='输入点要素类的完整路径')
    parser.add_argument('--id_field_fc', required=True, help='输入点要素类的连接字段')
    parser.add_argument('--csv_path', required=True, help='被连接的CSV文件的完整路径')
    parser.add_argument('--id_field_csv', required=True, help='csv文件的连接字段')
    parser.add_argument('--output_fc_fullpath', required=True, help='输出新要素类的完整路径')
    args = parser.parse_args()

    # 连接要素并另存为新要素类
    join_with_csv_to_new_feature(args.input_fc_fullpath, args.id_field_fc, args.csv_path, args.id_field_csv,
                                 args.output_fc_fullpath)


# ----------------------------
# 主程序入口
# ----------------------------
if __name__ == "__main__":
    main()